﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using ifunction.Fiddler.Model;

namespace ifunction.Fiddler.Configurator
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        List<DateTime> referenceStamps = new List<DateTime>();
        public MainWindow()
        {
            InitializeComponent();
        }

        #region UI events

        private void btn_Refresh_Click(object sender, RoutedEventArgs e)
        {
            mask_RequestList.Visibility = System.Windows.Visibility.Visible;
            btn_New.IsEnabled = btn_Refresh.IsEnabled = false;

            LoadRequestList(this.list_Requests);
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {

        }

        private void list_Requests_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ListBox container = sender as ListBox;

            if (container != null)
            {
                ListBoxItem selectedItem = container.SelectedItem as ListBoxItem;
                LoadRequestDetail(selectedItem.Tag);
            }
        }

        #endregion

        #region Core Actions

        /// <summary>
        /// Loads the request list.
        /// </summary>
        /// <param name="listView">The list view.</param>
        /// <param name="callback">The callback.</param>
        protected void LoadRequestList(ListBox listView)
        {
            Thread thread = new Thread(new ParameterizedThreadStart(LoadRequestListDelegate));
            thread.IsBackground = true;
            thread.Start(listView);
        }

        protected void LoadRequestListDelegate(object obj)
        {
            ListBox container = obj as ListBox;

            if (container != null)
            {
                //Todo


                container.Dispatcher.Invoke(new Action(() =>
                {
                    container.Items.Clear();
                    container.Items.Add(new ListBoxItem
                    {
                        Content = "test content",
                        Name = "Test",
                        Tag = new { Ts = 1, Tb = 2 }
                    });
                }));

                this.mask_RequestList.Dispatcher.Invoke(new Action(() =>
                {
                    this.mask_RequestList.Visibility = System.Windows.Visibility.Collapsed;
                    btn_New.IsEnabled = btn_Refresh.IsEnabled = true;
                }));
            }
        }

        /// <summary>
        /// Loads the request detail.
        /// </summary>
        public void LoadRequestDetail(object obj)
        {
            LoadPackageOnUI(obj as RequestPackage);
        }

        /// <summary>
        /// Loads the package configuration unique identifier.
        /// </summary>
        /// <param name="package">The package.</param>
        /// <param name="requestRawOnly">if set to <c>true</c> [request raw only].</param>
        public void LoadPackageOnUI(RequestPackage package, bool requestRawOnly = false)
        {
            if (package != null)
            {
                var mainRequest = FiddlerRequest.Create(package.MainRequestRaw);
                this.text_TargetUri.Text = mainRequest.TargetUri == null ? string.Empty : mainRequest.TargetUri.ToString();
                this.text_Referer.Text = mainRequest.RefererUri == null ? string.Empty : mainRequest.RefererUri.ToString();
                this.combo_Method.SelectedItem = mainRequest.Method;
                this.text_ContentType.Text = mainRequest.ContentType;
                this.text_Accept.Text = mainRequest.Accept;
                this.text_Cookie.Text = mainRequest.CookieString;
                this.text_UserAgent.Text = mainRequest.UserAgent;

                if (string.IsNullOrWhiteSpace(package.KeepSessionRequestRaw))
                {
                    this.combo_Interval.SelectedValue = 0;
                }
                else
                {
                    var keepSessionRequest = FiddlerRequest.Create(package.KeepSessionRequestRaw);
                    this.text_KeepSession_TargetUri.Text = mainRequest.TargetUri == null ? string.Empty : mainRequest.TargetUri.ToString();
                    this.text_KeepSession_Referer.Text = mainRequest.RefererUri == null ? string.Empty : mainRequest.RefererUri.ToString();
                    this.combo_KeepSession_Method.SelectedItem = mainRequest.Method;
                    this.text_KeepSession_ContentType.Text = mainRequest.ContentType;
                    this.text_KeepSession_Accept.Text = mainRequest.Accept;
                    this.text_KeepSession_Cookie.Text = mainRequest.CookieString;
                }

                if (!requestRawOnly)
                {
                    if (!string.IsNullOrWhiteSpace(package.KeepSessionRequestRaw))
                    {
                        this.combo_Interval.SelectedValue = package.KeepSessionInterval;
                    }

                    this.text_Name.Text = package.Name;
                    this.text_Key.Text = package.Key == null ? string.Empty : package.Key.Value.ToString();

                    Schedule? schedule = Schedule.Parse(package.Schedule);
                    if (schedule != null)
                    {
                        this.combo_ScheduleType.SelectedValue = schedule.Value.Type;
                        this.UC_EndStamp.SetDateTime(schedule.Value.EndStamp);
                        this.referenceStamps = schedule.Value.ReferenceStamps;
                        //this.text_DailyTimes.Text.=this.referenceStamps
                    }
                }
            }
        }

        protected RequestPackage LoadPackageFromUI()
        {
            RequestPackage package = new RequestPackage();

            package.Name = this.text_Name.Text;
            package.Key = this.text_Key.Text.ToGuid();

            FiddlerRequest mainRequest = new FiddlerRequest
            {
                Accept = this.text_Accept.Text,
                ContentType = this.text_ContentType.Text,
                CookieString = this.text_Cookie.Text,
                Method = (FiddlerRequest.MethodType)(this.combo_Method.SelectedItem),
                RefererUri = string.IsNullOrWhiteSpace(this.text_Referer.Text) ? null : new Uri(this.text_Referer.Text),
                TargetUri = string.IsNullOrWhiteSpace(this.text_TargetUri.Text) ? null : new Uri(this.text_TargetUri.Text),
                UserAgent = this.text_UserAgent.Text
            };

            package.MainRequestRaw = mainRequest.ToRaw();

            Schedule schedule = new Schedule
            {
                Type = (Schedule.ScheduleType)(this.combo_ScheduleType.SelectedValue.ToInt()),
                EndStamp = this.UC_EndStamp.GetDateTime(),
                ReferenceStamps = this.referenceStamps
            };
            package.Schedule = schedule.ToString();

            return package;
        }

        #endregion

        /// <summary>
        /// Handles the Click event of the btn_FillByRaw control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param>
        private void btn_FillByRaw_Click(object sender, RoutedEventArgs e)
        {
            FillParametersByRawWindow window = new FillParametersByRawWindow(this);
            window.Owner = this;
            window.Show();
        }

        /// <summary>
        /// Handles the SelectionChanged event of the combo_Interval control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="SelectionChangedEventArgs"/> instance containing the event data.</param>
        private void combo_Interval_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ComboBox box = sender as ComboBox;

            var value = ((ComboBoxItem)box.SelectedValue).Tag.ToLong();

            this.combo_KeepSession_Method.IsEnabled
                = this.text_KeepSession_Accept.IsEnabled
                = this.text_KeepSession_ContentType.IsEnabled
                = this.text_KeepSession_Cookie.IsEnabled
                = this.text_KeepSession_Referer.IsEnabled
                = this.text_KeepSession_TargetUri.IsEnabled
                = value > 0;
        }

        private void btn_Save_Click(object sender, RoutedEventArgs e)
        {

        }

        /// <summary>
        /// Handles the Loaded event of the MainWindow control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param>
        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            this.combo_KeepSession_Method.Items.Clear();
            this.combo_Method.Items.Clear();

            foreach (var one in Enum.GetValues(typeof(FiddlerRequest.MethodType)))
            {
                this.combo_KeepSession_Method.Items.Add(one);
                this.combo_Method.Items.Add(one);
            }

            this.combo_KeepSession_Method.SelectedIndex = 0;
            this.combo_Method.SelectedIndex = 0;

            this.combo_ScheduleType.Items.Clear();
            foreach (var one in Enum.GetValues(typeof(Schedule.ScheduleType)))
            {
                this.combo_ScheduleType.Items.Add(one);
            }
            this.combo_ScheduleType.SelectedIndex = 0;

            this.combo_Interval.Items.Clear();
            this.combo_Interval.Items.Add(new ComboBoxItem { Tag = 0, Content = "None" });
            this.combo_Interval.Items.Add(new ComboBoxItem { Tag = 5, Content = "5 Seconds" });
            this.combo_Interval.Items.Add(new ComboBoxItem { Tag = 30, Content = "30 Seconds" });
            this.combo_Interval.Items.Add(new ComboBoxItem { Tag = 60, Content = "1 Minute" });
            this.combo_Interval.Items.Add(new ComboBoxItem { Tag = 300, Content = "5 Minutes" });
            this.combo_Interval.Items.Add(new ComboBoxItem { Tag = 1800, Content = "30 Minutes" });
            this.combo_Interval.Items.Add(new ComboBoxItem { Tag = 3600, Content = "1 Hour" });
            this.combo_Interval.SelectedIndex = 0;
        }

        private void combo_ScheduleType_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ComboBox box = sender as ComboBox;

            var value = ((Schedule.ScheduleType)box.SelectedValue);
            this.btn_EditTimes.IsEnabled = value != Schedule.ScheduleType.Blood;
        }

        /// <summary>
        /// Handles the Click event of the btn_EditTimes control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param>
        private void btn_EditTimes_Click(object sender, RoutedEventArgs e)
        {
            ReferenceTimesWindow window = new ReferenceTimesWindow(this);
            window.Owner = this;
            window.Show();
        }


    }
}
